<template>
  <div class="coordinate-selector">
    <div class="axis-container">
      <div class="header">
        <span class="y-axis-header">{{ resourceTitle }}</span>
        <span class="x-axis-header" v-for="item in authList" :key="item.id">{{ item.name }}</span>
      </div>
      <div class="content" v-if="authList.length > 0">
        <el-scrollbar max-height="400px">
          <el-tree ref="treeRef" :data="resourceList" :props="props.resourceProps" show-checkbox node-key="id" @check="handleCheck" :expand-on-click-node="false" class="tree-content">
            <template #default="{ node, data }">
              <div class="custom-tree-node">
                <div class="tree-node-label">{{ node.label }}</div>
                <el-checkbox-group v-if="!data.hasChild" v-model="data.permission" @change="val => handleAuthCheck(val, data)" class="checkbox-group" @click.stop>
                  <el-checkbox v-for="auth in authList" :key="auth.id" :label="auth.id" :disabled="isAuthDisabled(data.id, auth.id)"><br /></el-checkbox>
                </el-checkbox-group>
              </div>
            </template>
          </el-tree>
        </el-scrollbar>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, defineProps, defineExpose, computed, onMounted } from 'vue'

const props = defineProps({
  resourceList: {
    type: Array,
    required: true
  },
  authList: {
    type: Array,
    required: true
  },
  resourceProps: {
    type: Object,
    default: () => {
      return {
        children: 'children',
        label: 'name'
      }
    }
  },
  resourceTitle: {
    type: String,
    default: '资源'
  },
  checkedList: { // 扁平数组
    type: Array,
    default: () => []
  },
  disabledList: { // 扁平数组
    type: Array,
    default: () => []
  }
})

const treeRef = ref(null)

// 初始化每个节点的permission和disabled状态
const initNodePermissions = nodes => {
  nodes.forEach(node => {
    if (!node.permission) {
      node.permission = []
    }
    // 设置初始勾选状态
    const checkedPerms = props.checkedList
      .filter(item => item.resourceId === node.id)
      .map(item => item.authId)
    const disabledPerms = props.disabledList
      .filter(item => item.resourceId === node.id)
      .map(item => item.authId)
    
    // 合并勾选和禁用的权限
    node.permission = [...new Set([...checkedPerms, ...disabledPerms])]
    node.disabledPerms = disabledPerms
    
    // 如果有禁用权限，设置节点为禁用状态
    if (disabledPerms.length > 0) {
      node.disabled = true
      treeRef.value?.setChecked(node.id, true, false)
    }

    if (node.children) {
      initNodePermissions(node.children)
    } else if (node.permission.length > 0) {
      treeRef.value?.setChecked(node.id, true, false)
    }
  })
}

// 判断某个权限是否禁用
const isAuthDisabled = (resourceId, authId) => {
  return props.disabledList.some(item => 
    item.resourceId === resourceId && item.authId === authId
  )
}

// 监听树节点的选中状态变化
const allAuth = computed(() => props.authList.map(item => item.id))
const handleCheck = (data) => {
  const node = treeRef.value.getNode(data.id)
  handleTreeCheck(data, node, node.checked)
}
const handleTreeCheck = (data, node, checked) => {
  // 引起的上级节点变化禁止触发触发该方法
  if (checked) {
    data.permission = [...allAuth.value]
  } else {
    // 取消选中时，保留禁用的权限
    data.permission = [...data.disabledPerms]
  }

  if (node.childNodes.length > 0) {
    node.childNodes.forEach(item => {
      handleTreeCheck(item.data, item, checked)
    })
  }
}

// 监听权限复选框组的变化
const handleAuthCheck = (value, nodeData) => {
  if (nodeData.permission.length > 0) {
    treeRef.value.setChecked(nodeData.id, true, false)
    setTimeout(() => {
      nodeData.permission = value
    },0)
  } else {
    treeRef.value.setChecked(nodeData.id, false, false)
  }
}

// 获取半选和选中节点数据
const getSelectedData = () => {
  const checkedNodes = treeRef.value.getCheckedNodes()
  // const halfCheckedNodes = treeRef.value.getHalfCheckedNodes()
  const result = []

  const processNodes = (nodes) => {
    nodes.forEach(node => {
      if (node.permission) {
        // 过滤掉禁用的权限
        const validPermissions = node.permission.filter(authId => 
          !props.disabledList.some(item => 
            item.resourceId === node.id && item.authId === authId
          )
        )

        validPermissions.forEach(authId => {
          result.push({
            resourceId: node.id,
            authId: authId
          })
        })
      }
    })
  }

  processNodes(checkedNodes)
  // processNodes(halfCheckedNodes)
  return result
}

onMounted(() => {
  initNodePermissions(props.resourceList)
})

// 暴露方法
defineExpose({
  getSelectedData
})
</script>

<style lang="scss" scoped>
.coordinate-selector {
  .axis-container {
    border: 1px solid #dcdfe6;

    .header {
      height: 40px;
      background-color: #f5f7fa;
      width: 100%;
      box-sizing: border-box;
      border-bottom: 1px solid #dcdfe6;
      padding-left: 46px;
      display: flex;
      align-items: center;

      span {
        flex-grow: 1;
        font-size: 14px;

        &.y-axis-header {
          min-width: 200px;
          flex-grow: 1;
        }

        &.x-axis-header {
          width: 100px;
          flex-grow: 0;
          text-align: center;
        }
      }
    }

    .content {
      .tree-content {
        :deep(.el-tree-node__content) {
          border-bottom: 1px solid #dcdfe6;
          height: 48px;
        }

        :deep(.el-tree-node__label) {
          width: 100%;
          .custom-tree-node {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%;

            .tree-node-label {
              flex-grow: 1;
            }

            .checkbox-group {
              display: flex;
              flex-grow: 0;

              .el-checkbox {
                width: 100px;
                justify-content: center;
                margin-right: 0;

                :deep(.el-checkbox__label) {
                  padding-left: 0;
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>
